home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
051-075
/
disk_075
/
comm
/
keyboard.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
11KB
|
345 lines
/* Comm keyboard routines */
#define KEYBOARD 1
#include "globals.h"
extern int capture;
#define ERR "\nKEY MACRO error."
#define KEYERR -1
#define NOMEM -2
#define OFFSET FN1 /* convert to cardinal number */
static UBYTE *string; /* temp string pointer */
static UBYTE workbuff[ SECSIZ ]; /* keyboard macro work area */
#define ENTRIES 112 /* keys on keyboard */
UBYTE toasc(code,qual)
USHORT qual,code;
{
static USHORT caps = FALSE;
UBYTE c;
static UBYTE nosh[ ENTRIES ] = {
'`','1','2','3','4','5','6','7',
'8','9','0','-','=',SLH,UND,'0',
'q','w','e','r','t','y','u','i',
'o','p','[',']',UND,'1','2','3',
'a','s','d','f','g','h','j','k',
'l',';',APS,UND,UND,'4','5','6',
UND,'z','x','c','v','b','n','m',
',','.','/',UND,'.','7','8','9',
' ',BKS,TAB,ENT,RET,ESC,DEL,UND,
UND,UND,'-',UND,CUP,CDN,CFW,CBK,
FN1,FN2,FN3,FN4,FN5,FN6,FN7,FN8,
FN9,F10,UND,UND,UND,UND,UND,HLP,
LSH,RSH,CAP,CTL,LAL,RAL,LAM,RAM,
LMB,RMB,MMB,UND,UND,UND,UND,UND
};
static UBYTE shift[ ENTRIES ] = {
'~','!','@','#','$','%','^','&',
'*','(',')','_','+','|',UND,'0',
'Q','W','E','R','T','Y','U','I',
'O','P','{','}',UND,'1','2','3',
'A','S','D','F','G','H','J','K',
'L',':','"',UND,UND,'4','5','6',
UND,'Z','X','C','V','B','N','M',
'<','>','?',UND,'.','7','8','9',
' ',BKS,TAB,ENT,RET,ESC,DEL,UND,
UND,UND,'-',UND,CUP,CDN,CFW,CBK,
SF1,SF2,SF3,SF4,SF5,SF6,SF7,SF8,
SF9,S10,UND,UND,UND,UND,UND,SHH,
LSH,RSH,CAP,CTL,LAL,RAL,LAM,RAM,
LMB,RMB,MMB,UND,UND,UND,UND,UND
};
switch(code)
{
case 98: caps = TRUE; break; /* caps lock pressed */
case 226: caps = FALSE; break; /* caps lock released */
}
if(code < ENTRIES)
{
c = nosh[ code ]; /* default lower case */
if(qual & 0x40) /* left amiga */
{
switch(c)
{
case 'p': return TOGPRT; /* Toggle printer */
case 'c': return TOGCAP; /* Toggle capture buffer */
case 's': return TOGSCR;
}
}
if(qual & 3)
return (shift[ code ]); /* shift key down */
if( isalpha(c) ) /* control or CAPS? */
{
if(qual & 8)
return(UBYTE)(shift[ code ] - '@');/* control down ? */
/* make it a control */
if ( caps ) /* caps lock down */
return ( shift[ code ]); /* make it upper case */
}
return (c);
}
return (UND); /* for release code */
} /* end of routine */
/*
Expand keyboard macros. Control characters are sent by prefixing the
ASCII equiv. with ^. Ex, control C is ^C, control X is ^X.
Also translates C type slash characters like \t, \r and \n.
In this implimentation, \n and \r generate the RETURN code (0xD).
Also, \w produces a 500 millisecond delay and \l produces a line break.
*/
void expand_macro(key)
char key;
{
key -= OFFSET; /* F1 becomes offset zero */
string = keymacro[ key ]; /* point to definition */
if(string == NULL) return; /* return if not defined */
sendout( string );
}
/* do the actual expansion. Send the characters to the modem */
sendout(str)
UBYTE *str;
{
static UBYTE macro[] = "00000000000000000000";
unsigned key;
UBYTE c;
while( c = *str++ ) /* do until end of string */
{
if( c == '^') { /* control character ^? */
if((c = *str++) == '^')
break;
else c = toupper(c)- 0x40; /* convert only valid chars */
}
else if( c == '\\') /* have an escape character? */
switch( c = tolower(*str++)) /* yes, get next character */
{
case 'r': c = '\r'; break; /* C equivilents */
case 'n': c = '\r'; break;
case 't': c = '\t'; break;
case 'f': c = '\f'; break;
case 'b': c = '\b'; break;
/* now my own */
/*
case 'p':
c = *str++;
if( c == '^')
c = toupper(*str++) - 0x40;
do {
key = readchar(10,0);
if( key == TIMEOUT ) break;
} while ( (tolower(key) != tolower(c)) );
continue;
*/
case 'l': /* line break */
SendBreak(); continue;
case 'w': /* delay 1/2 second */
Delay(25L);continue;
case 'm': /* expand another macro */
key = atoi(str);
while(isdigit(*str))
str++;
if( (key > 0) && (key <= KEYMACS) )
{
if(macro[ key -1 ] != '0')
{
emits_rx("\nKEY MACRO RECURSION not allowed -- or desired!\n");
continue;
}
macro[ key-1 ] = '1';
expand_macro( key - 1 + OFFSET );
macro[ key-1 ] = '0';
}
continue;
case '\\':break;
default: /* was really a \ character alone */
str--; /* adjust string pointer */
c = '\\'; /* and send the \ */
}
if(halfduplex)
emit_rx( c );
if(split_screen)
emit_tx( c ); /* echo it to the user */
if (capture && capton) /* capturing data to disk file? */
if (isprint(c)) buffer_it(c);
sendchar( c );
}
}
/* open keyboard macro file. Return 0 if not found, else return # of
macros in the library.
allocate memory for the macros and copy them to memory.
*/
int Init_keymacros()
{
USHORT i;
for(i = 0; i < KEYMACS; i++) /* init array of pointers */
keymacro[i] = NULL;
Load_keymacros(commkeys);
}
Load_keymacros(name)
UBYTE *name;
{
extern UBYTE *malloc();
int index, i;
FILE *inp;
UBYTE temp[42], *file, p[42];
if(*name == NULL) return; /* no name given */
strcpy(p,name);
i = strlen(p);
while(--i) /* remove trailing blanks from */
if(p[i] != ' ') break; /* filename */
if(i == 0) return; /* blank name given */
p[++i] = NULL;
index = 0;
strcpy(temp,install.DefDir);
strcat(temp,p);
file = name; /* try to open macro file */
if(( inp = fopen(p,"r")) == NULL) /* check default directory */
{
file = temp;
if((inp = fopen(temp,"r")) == NULL) /* then SYS: directory */
return NULL;
}
strcpy(commkeys,file);
Free_keymacros(); /* free any memory allocated */
while (fgets(workbuff,SECSIZ,inp)) /* do until end of file */
{
if(strlen(workbuff) < 3) continue; /* ignore short lines */
workbuff[ strlen(workbuff)-1 ] = NULL; /* kill trailing \n */
if((index = Add_keymacro()) == NOMEM) /* no memory left */
{
emits_rx("\nOut of memory\n");
break;
}
}
fclose(inp);
return index;
}
/* Save key macros to named file */
Save_keymacros(name)
UBYTE *name;
{
FILE *out;
USHORT i;
int error;
if((out = fopen(name,"w")) == NULL)
{
sprintf(sbuff,"\nCan't open file %s\n",name);
emits_rx(sbuff);
return NULL;
}
for(i = 0; i < KEYMACS; i++)
if( keymacro[ i ] )
fprintf(out,"%c%d%s\n",
(i > 9) ? 'S' : 'F',
(i > 9) ? i-9 : i+1,
keymacro[ i ]);
error = ferror(out);
fclose( out );
if( error )
{
emits_rx("Error during file write\n");
return NULL;
}
return OK;
}
/*
Return memory allocated for all key macros
*/
Free_keymacros()
{
int i;
for( i=0; i < KEYMACS; i++)
free_macro(i);
}
/*
Return memory allocated for single macro
*/
free_macro(num)
int num;
{
if(keymacro[ num ])
{
free(keymacro[ num ]);
keymacro[ num ] = NULL;
}
}
/*
Bring up the ASCII input window for macro entry
*/
Edit_keymacro()
{
workbuff[0] = NULL;
getstring(" USE","new key macro",workbuff,SECSIZ);
}
/*
Parse macro string and add it to macro list
*/
Add_keymacro()
{
int index, shift;
if(*workbuff == NULL) return NULL;
string = &workbuff[2];
if( (toupper(*workbuff) != 'F' && toupper(*workbuff) != 'S') ||
!isdigit(workbuff[1]))
{ /* line doesn't start with Fn or Sn */
emits_rx(ERR);
sprintf(sbuff,"\nExpected Fnn or Snn but read: %10s\n",workbuff);
emits_rx(sbuff);
return KEYERR;
}
shift = (toupper(*workbuff) == 'F') ? 0 : 10;
index = workbuff[1] - '1'; /* index is 0 to 9 */
if(workbuff[1] == '1')
if(workbuff[2] == '0')
{ /* F10 is ok */
string++; /* skip past extra 0 */
index = 9; /* make index 10 - 1 */
}
index += shift; /* account for shift Fnn key */
free_macro(index); /* if already allocated, deallocate it */
if(*string == NULL) return NULL;
keymacro[index] = malloc(strlen(string));
if(keymacro[index]) /* if allocation succeeded, copy string */
strcpy(keymacro[index],string);
else /* else, can't do it */
{
sprintf(sbuff,"\nCan't allocate memory for key macro F%d\n", index+1);
emits_rx(sbuff);
return NOMEM;
}
return index;
}